package com.bkhc.product.repository;

import com.bkhc.common.enu.ProductStatusEnum;
import com.bkhc.product.entity.Product;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@Repository
public interface ProductRepository extends JpaRepository<Product,String>, JpaSpecificationExecutor<Product> {

    default Page<Product> findAll(Product product, Pageable pageable){
        return findAll(new Specification<Product>() {
            @Override
            public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicate = new ArrayList<>();
                if(!StringUtils.isEmpty(product.getProductCode())){
                    predicate.add(criteriaBuilder.equal(root.get("productCode").as(String.class), product.getProductCode()));
                }
                if(!StringUtils.isEmpty(product.getProductName())){
                    predicate.add(criteriaBuilder.like(root.get("productName").as(String.class),"%"+ product.getProductName()+"%"));
                }
                if(product.getStatus()!=null){
                    predicate.add(criteriaBuilder.equal(root.get("status").as(String.class), product.getStatus().getCode()));
                }
                if (!StringUtils.isEmpty(product.getPartnerId())) {
                    predicate.add(criteriaBuilder.equal(root.get("partnerId").as(String.class), product.getPartnerId()));
                }
                Predicate[] pre = new Predicate[predicate.size()];

                return criteriaQuery.where(predicate.toArray(pre)).getRestriction();
            }
        },pageable);


    }

    Product findByProductCode(String productCode);

    void deleteByProductCode(String productCode);

    List<Product> findAllByStatus(ProductStatusEnum available);

    Product findByProductName(String productName);

    Product findById(int id);

    List<Product> findAllByPartnerId(String partnerId);

    List<Product>  findByProductCodeIn(List<String> productCodes);
}
